package com.google.forumbotty.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;

import com.google.forumbotty.model.AdminConfig;
import com.google.inject.Inject;

public class AdminConfigDaoImpl implements AdminConfigDao {
  private final Logger LOG = Logger.getLogger(AdminConfigDaoImpl.class.getName());
  private PersistenceManagerFactory pmf = null;

  @Inject
  public AdminConfigDaoImpl(PersistenceManagerFactory pmf) {
    this.pmf = pmf;
  }

  @Override
  public AdminConfig getAdminConfig(String id) {
    AdminConfig adminConfig = null;

    PersistenceManager pm = pmf.getPersistenceManager();

    try {
      Query query = pm.newQuery(AdminConfig.class);
      query.declareParameters("String id_");
      query.setFilter("id == id_");
      List<AdminConfig> adminConfigs = (List<AdminConfig>) query.execute(id);
      if (adminConfigs.size() > 0) {
        adminConfig = pm.detachCopy(adminConfigs.get(0));
      } else {
        adminConfig = new AdminConfig(id);

        // Each new AdminConfig by default has "public@a.gwave.com" as participant
        List<String> defaultParticipants = new ArrayList<String>();
        defaultParticipants.add("public@a.gwave.com");
        adminConfig.setDefaultParticipants(defaultParticipants);

        // Each new AdminConfig by default has its own id as the default tag
        List<String> defaultTags = new ArrayList<String>();
        defaultTags.add(id);
        adminConfig.setDefaultTags(defaultTags);

        pm.makePersistent(adminConfig);
        adminConfig = pm.detachCopy(adminConfig);
      }
    } finally {
      pm.close();
    }

    return adminConfig;
  }

  @Override
  public void addAutoTagRegex(String projectId, String tag, String regex) {
    AdminConfig adminConfig = getAdminConfig(projectId);
    adminConfig.getAutoTagRegexMap().put(tag, Pattern.compile(regex, Pattern.CASE_INSENSITIVE));
    save(adminConfig);
  }

  @Override
  public void removeAutoTagRegex(String projectId, String tag) {
    AdminConfig adminConfig = getAdminConfig(projectId);
    Map<String, Pattern> map = adminConfig.getAutoTagRegexMap();

    if (map.containsKey(tag)) {
      map.remove(tag);
      adminConfig.setAutoTagRegexMap(map);
      save(adminConfig);
    }
  }

  @Override
  public void addDefaultTag(String projectId, String tag) {
    AdminConfig adminConfig = getAdminConfig(projectId);
    List<String> tags = adminConfig.getDefaultTags();

    if (!tags.contains(tag)) {
      tags.add(tag);
      adminConfig.setDefaultTags(tags);
      save(adminConfig);
    }
  }

  @Override
  public void removeDefaultTag(String projectId, String tag) {
    AdminConfig adminConfig = getAdminConfig(projectId);
    List<String> tags = adminConfig.getDefaultTags();

    if (tags.contains(tag)) {
      tags.remove(tag);
      adminConfig.setDefaultTags(tags);
      save(adminConfig);
    }
  }

  @Override
  public void addDefaultParticipant(String projectId, String participantId) {
    AdminConfig adminConfig = getAdminConfig(projectId);
    List<String> participants = adminConfig.getDefaultParticipants();

    if (!participants.contains(participantId)) {
      participants.add(participantId);
      adminConfig.setDefaultParticipants(participants);
      save(adminConfig);
    }
  }

  @Override
  public void removeDefaultParticipant(String projectId, String participantId) {
    AdminConfig adminConfig = getAdminConfig(projectId);
    List<String> participants = adminConfig.getDefaultParticipants();

    if (participants.contains(participantId)) {
      participants.remove(participantId);
      adminConfig.setDefaultParticipants(participants);
      save(adminConfig);
    }
  }

  @Override
  public AdminConfig save(AdminConfig adminConfig) {
    PersistenceManager pm = pmf.getPersistenceManager();
    try {
      adminConfig = pm.makePersistent(adminConfig);
      adminConfig = pm.detachCopy(adminConfig);
    } finally {
      pm.close();
    }
    return adminConfig;
  }
}
